import random
from src.util.FrameImageUtil import *
from src.sprite.Bullet import *
from src.view.Progress import *


# 飞机精灵基类
class PlaneSprite(pygame.sprite.Sprite):

    def __init__(self):
        super(PlaneSprite, self).__init__()
        self.images = []
        self.hitImages = []
        self.destroyImages = []
        self.speed = 1  # 飞行速度
        self.energy = PLANE_LIFE_ENEMY_SMALL  # 当前血量
        self.rect = object
        self.is_alive = True  # 是否还活着
        self.hitIng = False  # 是否正在遭到攻击
        self.mask = object
        self.gifUtil = object
        self.bullet_group = pygame.sprite.Group()  # 子弹精灵组
        self.fireStep = HEAO_FIRE_STEP  # 发射子弹帧间隔
        self.harm = 1
        self.die_boom_music = pygame.mixer.Sound(BASE_RESOURCE_PATH_VOICE+"enemy1_down.wav")
        self.energyProgress = Progress()

    def initValue(self):
        self.rect = self.images[0].get_rect()
        self.is_alive = True
        self.mask = pygame.mask.from_surface(self.images[0])  # 碰撞检测去掉透明边距
        self.gifUtil = FrameImageUtil(self.images)
        self.energyProgress.setMax(self.energy)
        self.energyProgress.setPlaneRect(self.rect)

    # 步骤帧
    def step(self, step):
        self._move()

        isGIFOver = self.gifUtil.step(step)
        # 判断是否播放完动画
        if self.hitIng and self.is_alive and isGIFOver:
            self.gifUtil.setImages(self.images)  # 撞击动画播放完，没死恢复正常动画
            self.hitIng = False
        elif not self.is_alive and isGIFOver:
            self.died()  # 死亡动画播放完，可以去死了

        # 间隔发射子弹
        if not (step % self.fireStep):
            self.fire()
        # 更新子弹帧
        for bullet in self.bullet_group:
            bullet.step(self.step)

    def onDraw(self, canvas):
        # 播放gif图片组
        self.gifUtil.onDraw(canvas, self.rect)
        # 子弹绘制
        for bullet in self.bullet_group:
            bullet.onDraw(canvas)
        # 绘制血条
        self.energyProgress.onDraw(canvas)

    # 精灵移动
    def _move(self):
        self.rect.y += self.speed
        # 飞出屏幕的机删除，内存回收
        if self.rect.bottom < 0 or self.rect.y > SCREEN_RECT.height:
            self.kill()

    def rest(self):
        self.is_alive = True
        self.gifUtil.setImages(self.images)

    # 撞击，被击中
    def hit(self, harm):
        self.hitIng = True
        self.energy -= harm
        if self.energy <= 0:
            self.bomb()
        else:
            self.gifUtil.setImages(self.hitImages)  # 显示被攻击gif
        # 设置血条进度
        self.energyProgress.setProgress(self.energy)

    # 爆炸
    def bomb(self):
        self.is_alive = False
        self.gifUtil.setImages(self.destroyImages)
        self.die_boom_music.play()

    # 死亡状态回收资源
    def died(self):
        self.kill()

    # 开火发射子弹
    def fire(self):
        pass


# 敌机小
class SmallEnemy(PlaneSprite):

    def __init__(self):
        super(SmallEnemy, self).__init__()
        self.images = [pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy1.png")]
        self.hitImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy1_down1.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy1_down2.png")
        ]
        self.destroyImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy1_down3.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy1_down4.png")
        ]
        self.initValue()
        self.speed = random.randint(1, PLANE_MAX_SPEED_ENEMY_SMALL)
        # 指定位置
        self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width)


# 敌机中
class MiddleEnemy(PlaneSprite):

    def __init__(self):
        super(MiddleEnemy, self).__init__()
        self.images = [pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy2.png")]
        self.hitImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy2_down1.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy2_down2.png")
        ]
        self.destroyImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy2_down3.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy2_down4.png")
        ]
        self.speed = random.randint(1, PLANE_MAX_SPEED_ENEMY_MIDDLE)
        self.energy = PLANE_LIFE_ENEMY_MIDDLE  # 当前血量
        self.die_boom_music = pygame.mixer.Sound(BASE_RESOURCE_PATH_VOICE+"enemy2_down.wav")
        self.initValue()
        # 指定位置
        self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width)

    def hit(self, harm):
        super(MiddleEnemy, self).hit(harm)
        self.images = [pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy2_hit.png")]  # 受伤图片


# 敌机中
class BigEnemy(PlaneSprite):

    def __init__(self):
        super(BigEnemy, self).__init__()
        self.images = [pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_n1.png"),
                       pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_n2.png")
                       ]
        self.hitImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_down1.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_down2.png")
        ]
        self.destroyImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_down3.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_down4.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_down5.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_down6.png")
        ]
        self.speed = random.randint(1, PLANE_MAX_SPEED_ENEMY_BIG)
        self.energy = PLANE_LIFE_ENEMY_BIG  # 当前血量
        self.die_boom_music = pygame.mixer.Sound(BASE_RESOURCE_PATH_VOICE+"enemy3_down.wav")
        self.flying_music = pygame.mixer.Sound(BASE_RESOURCE_PATH_VOICE+"enemy3_flying.wav")
        self.flying_music.play(-1)
        self.initValue()
        # 指定位置
        self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width)

    def hit(self, harm):
        super(BigEnemy, self).hit(harm)
        self.images = [pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"enemy3_hit.png")]  # 受伤图片

    def bomb(self):
        self.flying_music.stop()
        super(BigEnemy, self).bomb()


#  玩家飞机，英雄
class Hero(PlaneSprite):

    def __init__(self):
        super(Hero, self).__init__()
        self.images = [pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"me1.png"),
                       pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"me2.png")]
        self.hitImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"me_destroy_1.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"me_destroy_2.png")
        ]
        self.destroyImages = [
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"me_destroy_3.png"),
            pygame.image.load(BASE_RESOURCE_PATH_IMAGE+"me_destroy_4.png")
        ]
        self.speed = 0
        self.heroSpeed = PLANE_HERO_SPEED
        self.energy = PLANE_LIFE_HERO  # 当前血量
        self.fire_music = pygame.mixer.Sound(BASE_RESOURCE_PATH_VOICE+"bullet.wav")
        self.die_boom_music = pygame.mixer.Sound(BASE_RESOURCE_PATH_VOICE+"me_down.wav")
        self.initValue()
        self.rect.centerx = SCREEN_RECT.width / 2
        self.rect.y = SCREEN_RECT.height * 2 / 3
        self.energyProgress.height = 5  # 血条高度
        self.energyProgress.setPlaneRect(pygame.Rect(0,
                                                     SCREEN_RECT.height + 10 - self.energyProgress.height,
                                                     SCREEN_RECT.width, SCREEN_RECT.height))

    def fire(self):
        bullet = Bullet(BULLET_TYPE_HERO_SMALL, self.rect.centerx, self.rect.top)
        self.bullet_group.add(bullet)
        self.fire_music.play()

    # 控制飞机移动，注意不能超出边界
    def moveUp(self):
        self.rect.top -= self.heroSpeed
        self.checkBounds()

    def moveDown(self):
        self.rect.top += self.heroSpeed
        self.checkBounds()

    def moveLeft(self):
        self.rect.left -= self.heroSpeed
        self.checkBounds()

    def moveRight(self):
        self.rect.left += self.heroSpeed
        self.checkBounds()

    def checkBounds(self):
        if self.rect.top < 0:
            self.rect.top = 0
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.right > SCREEN_RECT.width:
            self.rect.right = SCREEN_RECT.width
        if self.rect.bottom > SCREEN_RECT.height:
            self.rect.bottom = SCREEN_RECT.height

    def died(self):
        pygame.event.post(pygame.event.Event(pygame.USEREVENT, {"action": "gameover"}))
